package com.dave.gd.core.rule;

import java.util.EventObject;

import com.dave.gd.core.base.entity.impl.AbstractBaseEntity;

/**
 * 规则事件定义， 对象业务方法被调用前和后， 可以抛出相应的领域事件， 用于驱动相关规则。
 * 被驱动的规则可以通过事件内包含的：源对象、事件编码、参数列表、返回值， 访问到相关领域数据。
 * 事件的：方法编码， 参数列表和参数定义 ，与触发该事件的 业务方法一致
 * 
 */
public class RuleEvent extends EventObject {
    // 触发该事件业务方法的传入参数
    Object[] args;
    // 触发该事件业务方法的返回值，仅在after事件有效
    Object result;
    
    String execOpName;
    
    public Object[] getArgs() {
        return args;
    }
    
    public Object getResult() {
        return result;
    }
    
    public String getExecOpName() {
        return execOpName;
    }
    
    public RuleEvent(Object source) {
        super(source);
    }
    
    public RuleEvent(Object source, Object[] args, String opName) {
        super(source);
        this.args = args;
        this.execOpName = opName;
    }
    
    public RuleEvent(Object source, Object[] args, Object result) {
        super(source);
        this.args = args;
        this.result = result;
    }
    
    // 触发该事件的源领域对象，如:产品实例
    public AbstractBaseEntity getSouce() {
        return (AbstractBaseEntity) super.getSource();
    }
    
    public Object[] makeArgs(Object rule) {
        int size = 0;
        if (getArgs() != null) {
            size = getArgs().length;
        }
        // 构建参数列表
        Object[] args = new Object[size + 2];
        
        // 第一个参数是规则定义
        args[0] = rule;
        // 第二个参数是源业务对象this
        args[1] = getSource();
        // 后续参数为方法的入参
        if (getArgs() != null) {
            for (int i = 0; i < getArgs().length; i++) {
                args[2 + i] = getArgs()[i];
            }
        }
        
        return args;
    }
    
    public Object getArg(int i) {
        if (i > this.getArgs().length) {
            throw new RuntimeException("方法参数定义的顺序 ，超过实际参数数量");
        }
        return args[i];
    }
}
